﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Windows.Forms;
using Keys = Microsoft.Xna.Framework.Input.Keys;

namespace SpriteBuilder
{
    /// <summary>
    /// Managerclass for the Sprites
    /// controles selecting and dragging for them
    /// </summary>
    class TextureElementsManager
    {
        private List<EditorTextureElement> Elements = new List<EditorTextureElement>();
        private List<EditorTextureElement> selectedElements = new List<EditorTextureElement>();
        MainFrameForm EditorForm;
        EditorTextureElement dragedElement = null;

        Vector2 Viereckstart;
        Vector2 Viereckend;
        Line TopLine;
        Line BotLine;
        Line LeftLine;
        Line RightLine;

        public TextureElementsManager(MainFrameForm editorform)
        {
            EditorForm = editorform;
            Viereckstart = new Vector2();
            Viereckend = new Vector2();
            TopLine = LineManager.addLine(new Vector2(0, 0), new Vector2(0, 0), 1, Color.Black, 0.1f);
            BotLine = LineManager.addLine(new Vector2(0, 0), new Vector2(0, 0), 1, Color.Black, 0.1f);
            LeftLine = LineManager.addLine(new Vector2(0, 0), new Vector2(0, 0), 1, Color.Black, 0.1f);
            RightLine = LineManager.addLine(new Vector2(0, 0), new Vector2(0, 0), 1, Color.Black, 0.1f);
        }

        public void insertElement(EditorTextureElement Element)
        {
            Elements.Add(Element);
        }

        public void Draw(SpriteBatch spritebatch)
        {
            for (int i = 0; i < Elements.Count; i++)
                Elements[i].Draw(spritebatch);

            LineManager.Draw(spritebatch);
        }

        public void Update(GameTime time, InputManager input)
        {
            selectwithleftClick(input);

            deselectWithRightClick(input);

            bool isDragging = dragSelectedElements(input);

            multiselectwithRectangle(input, isDragging);
        }

        private void multiselectwithRectangle(InputManager input, bool isDragging)
        {
            if (input.presentMouseCondition == MouseCondition.leftPress && !isDragging)
            {
                Viereckstart = input.TransformedMouseCoords;
                Viereckend = input.TransformedMouseCoords;
            }

            if (input.presentMouseCondition == MouseCondition.holdleft && !isDragging)
            {
                Viereckend = input.TransformedMouseCoords;
            }

            TopLine.Start = Viereckstart;
            TopLine.End = new Vector2(Viereckend.X, Viereckstart.Y);
            BotLine.Start = new Vector2(Viereckstart.X, Viereckend.Y);
            BotLine.End = Viereckend;
            LeftLine.Start = Viereckstart;
            LeftLine.End = new Vector2(Viereckstart.X, Viereckend.Y);
            RightLine.Start = new Vector2(Viereckend.X, Viereckstart.Y);
            RightLine.End = Viereckend;

            if (input.presentMouseCondition == MouseCondition.leftClick && !isDragging)
            {
                Vector2 HeightWidth = Viereckend - Viereckstart;
                Rectangle selectRectangle;
                if (HeightWidth.X < 0 && HeightWidth.Y < 0)
                    selectRectangle = new Rectangle((int)Viereckend.X, (int)Viereckend.Y, (int)-HeightWidth.X, (int)-HeightWidth.Y);
                else if (HeightWidth.X < 0 && HeightWidth.Y > 0)
                    selectRectangle = new Rectangle((int)Viereckend.X, (int)(Viereckend.Y - HeightWidth.Y), (int)-HeightWidth.X, (int)HeightWidth.Y);
                else if (HeightWidth.X > 0 && HeightWidth.Y < 0)
                    selectRectangle = new Rectangle((int)Viereckstart.X, (int)(Viereckstart.Y + HeightWidth.Y), (int)HeightWidth.X, (int)-HeightWidth.Y);
                else
                    selectRectangle = new Rectangle((int)Viereckstart.X, (int)Viereckstart.Y, (int)HeightWidth.X, (int)HeightWidth.Y);

                if (selectRectangle.Width * selectRectangle.Height > 100)
                {
                    if (!input.KeyboardState.IsKeyDown(Keys.LeftShift))
                    {
                        for (int j = 0; j < selectedElements.Count; j++)
                            selectedElements[j].marked = false;
                        selectedElements.Clear();
                    }
                    for (int i = 0; i < Elements.Count; i++)
                    {
                        if (selectRectangle.Intersects(Elements[i].dstRectangle))
                        {
                            if (!Elements[i].marked)
                            {
                                Elements[i].marked = true;
                                selectedElements.Add(Elements[i]);
                                EditorForm.setPropGrid(Elements[i]);
                            }
                            else
                            {
                                Elements[i].marked = false;
                                selectedElements.Remove(Elements[i]);
                                EditorForm.setPropGrid(null);
                            }
                        }
                    }
                }
                Viereckstart = input.TransformedMouseCoords;
                Viereckend = input.TransformedMouseCoords;
            }
        }

        private bool dragSelectedElements(InputManager input)
        {
            for (int i = 0; i < selectedElements.Count; i++)
            {
                Point p = new Point((int)input.TransformedMouseCoords.X, (int)input.TransformedMouseCoords.Y);
                if (input.presentMouseCondition == MouseCondition.leftPress)
                {
                    if (selectedElements[i].dstRectangle.Contains(p))
                    {
                        dragedElement = Elements[i];
                        break;
                    }
                }
            }
            if (dragedElement != null)
            {
                switch (input.presentMouseCondition)
                {
                    case MouseCondition.leftClick:
                    case MouseCondition.rightClick:
                    case MouseCondition.holdright:
                    case MouseCondition.doubleleftClick:
                        dragedElement = null;
                        break;
                    case MouseCondition.holdleft:
                    case MouseCondition.leftPress:
                        for (int i = 0; i < selectedElements.Count; i++)
                        {
                            selectedElements[i].Position += new Vector2(input.TransformedMouseCoords.X - input.TransformedOldMouseCoords.X, input.TransformedMouseCoords.Y - input.TransformedOldMouseCoords.Y);
                        }
                        break;
                    default:
                        break;
                }
            }
            return dragedElement != null;
        }

        private void deselectWithRightClick(InputManager input)
        {
            if (input.presentMouseCondition == MouseCondition.rightClick)
            {
                for (int i = 0; i < Elements.Count; i++)
                {
                    Point p = new Point((int)input.TransformedMouseCoords.X, (int)input.TransformedMouseCoords.Y);
                    if (Elements[i].dstRectangle.Contains(p))
                    {
                        for (int j = 0; j < selectedElements.Count; j++)
                            selectedElements[j].marked = false;
                        selectedElements.Clear();
                        Elements[i].marked = true;
                        selectedElements.Add(Elements[i]);
                        EditorForm.setPropGrid(Elements[i]);
                        break;
                    }

                    if (i == Elements.Count - 1)
                    {
                        for (int j = 0; j < selectedElements.Count; j++)
                            selectedElements[j].marked = false;
                        selectedElements.Clear();
                        EditorForm.setPropGrid(null);
                    }
                }
            }
        }

        private void selectwithleftClick(InputManager input)
        {
            if (input.presentMouseCondition == MouseCondition.leftPress)
            {
                for (int i = 0; i < Elements.Count; i++)
                {
                    Point p = new Point((int)input.TransformedMouseCoords.X, (int)input.TransformedMouseCoords.Y);
                    if (Elements[i].dstRectangle.Contains(p))
                    {
                        if (!input.KeyboardState.IsKeyDown(Keys.LeftShift) && !Elements[i].marked)
                        {
                            for (int j = 0; j < selectedElements.Count; j++)
                                selectedElements[j].marked = false;
                            selectedElements.Clear();
                        }

                        if (input.KeyboardState.IsKeyDown(Keys.LeftShift))
                        {
                            if (!Elements[i].marked)
                            {
                                Elements[i].marked = true;
                                selectedElements.Add(Elements[i]);
                                EditorForm.setPropGrid(Elements[i]);
                                break;
                            }
                            else
                            {
                                Elements[i].marked = false;
                                selectedElements.Remove(Elements[i]);
                                EditorForm.setPropGrid(null);
                                break;
                            }
                        }
                        else
                        {
                            if (!Elements[i].marked)
                            {
                                Elements[i].marked = true;
                                selectedElements.Add(Elements[i]);
                                EditorForm.setPropGrid(Elements[i]);
                                break;
                            }
                            else
                                break;
                        }
                    }
                }
            }

        }


    }
}
